home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / LIBRARY / PBLIB1 / UNITS / PBHELP.PAS < prev    next >
Pascal/Delphi Source File  |  1994-05-03  |  15KB  |  470 lines

  1. {SECTION ..PbHELP }
  2. UNIT PbHELP;
  3.  
  4. INTERFACE
  5.  
  6. uses CRT, PbCRT, PbWIND, PbMISC, PbDATA, PbOBJS, PbSELECT;
  7.  
  8. {
  9. Description:  Simple windowed help
  10.  
  11. Author      : Howard Richoux
  12. Date        : 12/30/90
  13. Last revised: 1/1/94  hnr   Not so simple HELP - section support
  14.               2/18/94 HNR   NEW LIBRARIES
  15. Application : IBM PC and compatibles, done in Turbo Pascal 5.x
  16. Status      : Placed in the Public Domain by HNR Software 1/29/1994
  17. Published in: none
  18.  
  19.     A HELP file is simply a text file which has been divided into
  20. named sections with something like '?section one'.
  21.  
  22.     The two DISPLAYHELP procedures load the named section into a string
  23. array, use a few keys to page around in it, and dispose of the section on exit.
  24.  
  25.     the DOHELP procedures provide the window for the display routines.
  26.  
  27. Notes - 1/2/94 - section seek seems to work OK, but I am suspicious of
  28.    the currentposition reported out of TFILE_object. Check further.
  29. }
  30.  
  31. var HelpMaxLines : integer;
  32.  
  33. {-}
  34. {SECTION .HELP_object }
  35. type HELP_object = object(STRA_object)
  36.      Procedure loadsectionseek(fname,stag,sname : string;posn : longint);
  37.      end;
  38. {SECTION .Procs }
  39. {+}
  40.  
  41.  
  42. Procedure DisplayHelp(HLP : HELP_object; rows,cols : byte;var cmd : string);
  43.                  {[MISC] HELP is sectioned text file returns exit command}
  44.  
  45. Procedure DoHelp(fname,secttag,sname : string;var cmd : string);
  46.                  {[MISC] single section full screen}
  47.  
  48. Procedure DoHelpW(fname,secttag,sname : string;
  49.                      x0,y0,rows,cols : byte; var cmd : string);
  50.                  {[MISC] single section, return exit command}
  51.  
  52. Procedure DoHelpPosn(fname,secttag,sname : string;
  53.                      posn : longint; var cmd : string);
  54.                  {[MISC] single section using positioning}
  55.  
  56. Procedure DoHelpFileView(fn,secttag : string; var cmd : string);
  57.                  {[MISC] Whole file by section selection}
  58.  
  59.  
  60. {-}
  61. {
  62.    This form of a help system will consist of data taken from a text file
  63.    which has been divided into '?SECTION's.
  64.  
  65.    The unit will read the file and keep the section names for selection.
  66.  
  67.    When a section has been selected, The section will be read into a
  68.    string array and displayed as requested.  Upon exit from HELP, the
  69.    array will be disposed of.
  70.  
  71.    This is NOT a 'tight' piece of code, I just want something NOW.
  72. }
  73. {+}
  74.  
  75.  
  76. {SECTION .zImplementation }
  77. IMPLEMENTATION
  78.  
  79. var sections   : HOLD_object;  { holds section names }
  80.     keys       : STRA_object;  { holds keywords  }
  81.  
  82.  
  83. {SECTION  HELP_object }
  84. Procedure HELP_object.loadsectionseek(fname,stag,sname : string;
  85.                                       posn : longint);
  86. var secttag,sectname  : string[40];
  87.     ok, found : boolean;
  88.     sectlen   : integer;
  89.     s     : string;
  90.     i     : integer;
  91.     TEXTF : TFILE_object;
  92.      begin
  93.      i := 0;
  94.      found := false;
  95.      secttag  := UpcaseStr(stag);
  96.      sectname := UpcaseStr(sname);
  97.      sectlen  := length(sectname);
  98.      trim(sectname);
  99.      TEXTF.init(fname,false);
  100.      ok := TEXTF.opened;
  101.      if ok then TEXTF.seek(posn-200);  { position near then read forward }
  102.      while ok do                       { why ?? }
  103.           begin
  104.           ok := TEXTF.fetchnext(s);
  105.           if ok then
  106.                begin
  107.                if secttag = leftstr(UpCaseStr(s),length(secttag)) then
  108.                      begin
  109.                     { writeln(posn,' ',TEXTF.currentposition,
  110.                              ' [',s,']');
  111.                      pause;}
  112.                      if found then
  113.                           begin
  114.                           found := false;
  115.                           ok := false;
  116.                           end
  117.                      else begin
  118.                           delete(s,1,length(secttag));
  119.                           trim(s);
  120.                           if leftstr(UpCaseStr(s),sectlen) = sectname then
  121.                                 found := true;
  122.                           end;
  123.                      end
  124.                else if found then ok := HELP_object.append(s);
  125.                end;
  126.           end;
  127.      TEXTF.done;
  128.      end;
  129.  
  130.  
  131.  
  132. {SECTION  LoadHELPSection }
  133. Procedure LoadHELPSection(fn,secttag,sectname : string;
  134.                           var HLP : HELP_object);
  135. var s : string[1];
  136.      begin
  137.      HLP.init(HelpMaxLines);  {max lines per help section}
  138.      if secttag <> '' then HLP.loadsection(fn,secttag,sectname)
  139.      else HLP.load(fn);
  140.      if HLP.count = 0 then
  141.           begin
  142.           if not fileexists(fn) then
  143.                writeln('Help file does not exist [',fn,']')
  144.           else writeln('Cannot file Help section [',sectname,']');
  145.           end;
  146.      end;
  147.  
  148.  
  149. {SECTION  LoadHELPSectionPosn }
  150. Procedure LoadHelpSectionPosn(fn,secttag,sectname : string; posn : longint;
  151.                           var HLP : HELP_object);
  152. var s : string[1];
  153.      begin
  154.      HLP.init(HelpMaxLines);  {max lines per help section}
  155.      HLP.loadsectionseek(fn,secttag,sectname,posn);
  156.      if HLP.count = 0 then
  157.           begin
  158.           if not fileexists(fn) then
  159.                writeln('Help file does not exist [',fn,']')
  160.           else writeln('Cannot file Help section [',sectname,']');
  161.           end;
  162.      end;
  163.  
  164.  
  165. {SECTION  DisplayHelp }
  166. Procedure DisplayHelp(HLP : HELP_object; rows,cols : byte;var cmd : string);
  167. var s       : string;
  168.     first,incr,prev,n,xrows   : integer;
  169.      begin
  170.      xrows := rows-3;
  171.      cmd := '?HOME';
  172.      first := 1;
  173.      while (cmd <> '?ESCAPE') and (cmd <> '?SCREENPR') and
  174.            (cmd <> '?LEFTARR') and (cmd <> '?RIGHTARR') do
  175.           begin
  176.           if (incr = 1) then
  177.                begin
  178.                n := (first+xrows-1);
  179.                if (n<>prev) then writeln(HLP.fetchN(n));
  180.                prev := n;
  181.                end
  182.           else begin
  183.                clrscr;
  184.                HLP.listpage(first,xrows,cols);
  185.                end;
  186.           GetKeycmd(cmd);
  187.           incr := 0;
  188.           if      cmd = '?UP'      then incr := -1*xrows
  189.           else if cmd = '?DOWN'    then incr := xrows
  190.           else if cmd = '?DOWNARR' then incr := 1
  191.           else if cmd = '?UPARR'   then incr := -1
  192.           else if cmd = '?HOME'    then first := 1
  193.           else if cmd = '?END'     then first := 9999;
  194.           first := first + incr;
  195.           if ((first+rows) > HLP.count) then first := HLP.count - (xrows-1);
  196.           if (first < 1) then first := 1;
  197.           end;
  198.      end;
  199.  
  200.  
  201. {SECTION  DoHelp }
  202. Procedure DoHelp(fname,secttag,sname : string;var cmd : string);
  203. var wndw    : WINDOW_object;
  204.     fn      : string[40];
  205.     HLP     : HELP_object;
  206.      begin
  207.      fn := fname;
  208.      if fn = '' then
  209.           begin
  210.           fn := paramstr(0);
  211.           ForceExt(fn,'hlp');
  212.           end;
  213.      wndw.init(1,5,18,78,0);
  214.      wndw.setlabels(' '+fname+' ['+sname+'] ',' ESC-Exit/Arr&Pg-move ');
  215.      wndw.PopUp;
  216.      wndw.smallwindow;
  217.      LoadHelpSection(fn,secttag,sname,HLP);
  218.      DisplayHelp(HLP,16,76,cmd);
  219.      HLP.done;
  220.      wndw.done;
  221.      end;
  222.  
  223.  
  224.  
  225. {SECTION  DoHelpPosn }
  226. Procedure DoHelpPosn(fname,secttag,sname : string;
  227.                      posn : longint;var cmd : string);
  228. var wndw    : WINDOW_object;
  229.     fn      : string[40];
  230.     HLP     : HELP_object;
  231.      begin
  232.      fn := fname;
  233.      if fn = '' then
  234.           begin
  235.           fn := paramstr(0);
  236.           ForceExt(fn,'hlp');
  237.           end;
  238.      wndw.init(1,5,18,78,0);
  239.      wndw.setlabels(' '+fname+' ['+sname+'] ',' ESC-Exit/Arr&Pg-move ');
  240.      wndw.PopUp;
  241.      wndw.smallwindow;
  242.      LoadHelpSectionPosn(fn,secttag,sname,posn,HLP);
  243.      DisplayHelp(HLP,16,76,cmd);
  244.      HLP.done;
  245.      wndw.done;
  246.      end;
  247.  
  248.  
  249. {SECTION  DoHelpW }
  250. Procedure DoHelpW(fname,secttag,sname : string;
  251.                      x0,y0,rows,cols : byte; var cmd : string);
  252. var wndw    : WINDOW_object;
  253.     fn      : string[40];
  254.     HLP     : HELP_object;
  255.     sz      : string[14];
  256.      begin
  257.      fn := fname;
  258.      if fn = '' then
  259.           begin
  260.           fn := paramstr(0);
  261.           ForceExt(fn,'hlp');
  262.           end;
  263.      LoadHelpSection(fn,secttag,sname,HLP);
  264.      sz := '['+integerstr(HLP.count,4);
  265.      removeblanks(sz);
  266.      sz := sz + ' lines]';
  267.      wndw.init(x0,y0,x0+cols+2,y0+rows+1,0);
  268.      wndw.setlabels(' '+fname+' ['+sname+'] ',' ESC-Exit/Arr&Pg-move '+sz);
  269.      wndw.PopUp;
  270.      wndw.smallwindow;
  271.      DisplayHelp(HLP,rows,cols,cmd);
  272.      HLP.done;
  273.      wndw.done;
  274.      end;
  275.  
  276.  
  277. {SECTION  DoHelpFileView }
  278. {PAGE}
  279.  
  280. { Full sectioned text file browsing   DoHelpFileView(fname,sectiontag); }
  281.  
  282.  
  283. Procedure UpdateKeysList(var keys : STRA_object; str : string);
  284. var s,s1 : string;
  285.     i : integer;
  286.      begin
  287.      s := trimstr(str);
  288.      patchstr(s,'{',' ');
  289.      patchstr(s,'[',' ');
  290.      patchstr(s,']',' ');
  291.      patchstr(s,'}',' ');
  292.      while length(s) > 0 do
  293.           begin
  294.           trim(s);
  295.           s1 := GetLeftStr(s,' ');
  296.           i := keys.linearfind(s1);
  297.           if i = 0 then keys.append(s1);
  298.           end;
  299.      end;
  300.  
  301.  
  302. Procedure BuildHelpSectionIndex(fn : string; secttag, filter : string;
  303.                        var sections : HOLD_object; var keys : STRA_object);
  304. var t0       : TFILE_object;
  305.     taglen   : integer;
  306.     posn     : longint;
  307.     s,s1,stag : string;
  308.     i        : integer;
  309.      begin
  310.      writeln('Indexing ',fn,' ',secttag,'  Please wait a few seconds.');
  311.     { pause;}
  312.      taglen  := length(secttag);
  313.      stag    := UpCaseStr(secttag);
  314.      posn    := 0;
  315.      t0.init(fn,false);
  316.      while t0.fetchnext(s) do
  317.           begin
  318.           if (UpCaseStr(leftstr(s,taglen)) = stag) then
  319.                begin
  320.                delete(s,1,taglen);
  321.                trim(s);
  322.                s1 := GetLeftStr(s,' ');
  323.                UpdateKeysList(keys,s);
  324.                if (s1 <> '') then
  325.                     begin
  326.                   { writeln('section - ',s1);}
  327.                     if filter = '' then sections.append(s1,posn)
  328.                     else begin
  329.                          i := pos(filter,s); {check the keywords}
  330.                          if i > 0 then sections.append(s1,posn);
  331.                          end;
  332.                     end;
  333.                end;
  334.           posn := t0.currentposition;
  335.           end;
  336.      t0.done;
  337.      end;
  338.  
  339.  
  340. Procedure LoadHelpSections(fn : string; secttag, filter : string;
  341.                        var sections : HOLD_object; var keys : STRA_object);
  342. var txxname,keyname : string;
  343.      begin
  344.      if filter = '' then
  345.           begin
  346.           txxname := fn; forceext(txxname,'txx');
  347.           keyname := fn; forceext(keyname,'key');
  348.           if fileexists(txxname) and
  349.             (filedate(fn,'') < filedate(txxname,'')) then
  350.                begin
  351.                sections.load(txxname);
  352.                keys.load(keyname);
  353.                end
  354.           else begin
  355.                BuildHelpSectionIndex(fn,secttag,'',sections,keys);
  356.                sections.sort;
  357.                sections.save(txxname);
  358.                keys.sort;
  359.                keys.save(keyname);
  360.                end;
  361.           end
  362.      else begin
  363.           BuildHelpSectionIndex(fn,secttag,filter,sections,keys);
  364.           keys.sort;
  365.           sections.sort;
  366.           end;
  367.      writeln('Sections = ',sections.count);
  368.      end;
  369.  
  370.  
  371. Procedure HelpViewCommand(var cmd : string; var sections : HOLD_object;
  372.                           var itemselect : integer);
  373.      begin
  374.      if cmd = '?LEFTARR' then
  375.           begin
  376.           dec(itemselect);
  377.           if itemselect < 1 then itemselect := 1;
  378.           cmd := '?SELECTED';
  379.           end
  380.      else if cmd = '?RIGHTARR' then
  381.           begin
  382.           inc(itemselect);
  383.           if itemselect > sections.count then
  384.                itemselect := sections.count;
  385.           cmd := '?SELECTED';
  386.           end
  387.      else begin
  388.           cmd := '?RESELECT';
  389.           end;
  390.      end;
  391.  
  392.  
  393. Procedure DoHelpWCmdPosn(fname,secttag,sname : string; posn : longint;
  394.                      x0,y0,rows,cols : byte; var cmd : string);
  395. var wndw    : WINDOW_object;
  396.     fn      : string[40];
  397.     HLP     : HELP_object;
  398.      begin
  399.      fn := fname;
  400.      if fn = '' then
  401.           begin
  402.           fn := paramstr(0);
  403.           ForceExt(fn,'hlp');
  404.           end;
  405.      LoadHelpSectionPosn(fn,secttag,sname,posn,HLP);
  406.      wndw.init(x0,y0,x0+cols+2,y0+rows-1,0);
  407.      wndw.setlabels(' '+fname+' ['+sname+'] ',
  408.                     ' ESC-Exit/Arr&Pg-move ');
  409.      wndw.PopUp;
  410.      wndw.smallwindow;
  411.      {HLP.save('junk.txt');}
  412.      DisplayHelp(HLP,rows,cols,cmd);
  413.      HLP.done;
  414.      wndw.done;
  415.      end;
  416.  
  417.  
  418. Procedure ChooseNewFilter(var fn,secttag,filter : string);
  419. var itemselect : integer;
  420.     cmd : string;
  421.      begin
  422.      itemselect := 1;
  423.      SetSelectwindow(1,1,22,4,15);  { x0,y0,x1,columns,colwidth}
  424.      SetSelectWindowLabels(' File: '+fn+'    keyword: '+filter+' ',
  425.                            ' Choose a Filter ');
  426.      Select(keys,filter,itemselect,cmd);
  427.      sections.done;
  428.      sections.init(1000);
  429.      LoadHelpSections(fn,secttag,filter,sections,keys);
  430.      end;
  431.  
  432.  
  433. Procedure DoHelpFileView(fn,secttag : string; var cmd : string);
  434. var sectname   : string[40];
  435. var itemselect : integer;
  436.     filter     : string;
  437.     posn       : longint;
  438.      begin
  439.      filter := '';
  440.      itemselect := 1;
  441.      HelpMaxLines := 100;
  442.      cmd        := '?RESELECT';
  443.      sections.init(1000);
  444.      keys.init(200);
  445.      LoadHelpSections(fn,secttag,filter,sections,keys);
  446.      while itemselect > 0 do
  447.           begin
  448.           SetSelectwindow(1,1,22,4,15);  { x0,y0,x1,columns,colwidth}
  449.           SetSelectWindowLabels(' File: '+fn+'    keyword: '+filter+' ',
  450.                                 ' Select a Section / F5 - choose filter ');
  451.           Select(sections,sectname,itemselect,cmd);
  452.           if cmd = '?FKEY5' then ChooseNewFilter(fn,secttag,filter);
  453.           while (cmd = '?SELECTED') do
  454.               begin
  455.               sectname := sections.fetchStrN(itemselect);
  456.               posn     := sections.fetchNumN(itemselect);
  457.               DoHelpWCmdPosn(fn,secttag,sectname,posn,1,1,22,77,cmd);
  458.               HelpViewCommand(cmd,sections,itemselect);
  459.               end;
  460.           end;
  461.      sections.done;
  462.      keys.done;
  463.      end;
  464.  
  465.  
  466. {SECTION  zzInitialization }
  467.      begin {Initialization }
  468.      HelpMaxLines := 300;
  469.      end.
  470.